﻿using System;
using System.Windows.Forms;
using GuidanceExplorer;
using GuidanceExplorer.Controls;
using GuidanceExplorer.Model;
using GuidanceExplorerAddIn.EventsArgs;


namespace GuidanceExplorerAddIn.Controls
{
    /// <summary>
    /// Specifies the nodes to be shown in the LibrariesBrowser
    /// </summary>
    public enum GuidanceNodeTypes
    {
        /// <summary>
        /// All nodes
        /// </summary>
        All,
        /// <summary>
        /// Only Library nodes
        /// </summary>
        OnlyLibraries,
        /// <summary>
        /// Only Read/Write libraries
        /// </summary>
        ReadWriteLibraries,
        /// <summary>
        /// Only Read-Only libraries
        /// </summary>
        ReadOnlyLibraries,
        /// <summary>
        /// Nodes where a SearchView can be added
        /// </summary>
        SearchViewLocation,
        /// <summary>
        /// Read Write views (to drag items)
        /// </summary>
        ReadWriteViews
    }

    public partial class ViewsBrowser : Form
	{
		#region Private Members
		/// <summary>
        /// Current Guidance object
        /// </summary>
        private Guidance _guidance;
        /// <summary>
        /// The guidance nodes that will be displayed.
        /// </summary>
        private GuidanceNodeTypes _nodeTypes;
		// Event Handlers
		public event EventHandler<NewViewEventArgs> OnNewView;
        public event EventHandler<NewChecklistEventArgs> OnNewChecklist;
        #endregion

		public ViewsBrowser()
        {
            InitializeComponent();
		}

		#region Private Methods
        private void AddNodes(FolderCollection folders, ViewCollection views, ChecklistCollection checklists, TreeNode node)
        {
            
            if (_nodeTypes == GuidanceNodeTypes.ReadWriteViews)
            {
                //add checklists
                if (checklists != null)
                {
                    foreach (GuidanceExplorer.Model.Checklist checklist in checklists.Values)
                    {
                        ChecklistNode chklstNode = ChecklistNode.New();
                        chklstNode.Text = checklist.Caption;
                        chklstNode.ModelInstance = checklist;
                        node.Nodes.Add(chklstNode);
                    }
                }
                //add views
                foreach (GuidanceExplorer.Model.View childView in views.Values)
                {
                    if (!(childView is SearchView))
                    {
                        ViewNode viewNode = ViewNode.New();
                        viewNode.Text = childView.Caption;
                        viewNode.ModelInstance = childView;
                        node.Nodes.Add(viewNode);
                    }
                }
            }
            //Add folders
            foreach (GuidanceExplorer.Model.Folder childFolder in folders.Values)
            {
                AddFolder(childFolder, node);
            }
        }
    
        private void AddFolder(GuidanceExplorer.Model.Folder folder, TreeNode parent)
        {
            FolderNode node = FolderNode.New();
            node.Text = folder.Caption;
            node.ModelInstance = folder;
            parent.Nodes.Add(node);

            AddNodes(folder.Folders,folder.Views, folder.Checklists, node);
        }
		#endregion

		#region Properties
		/// <summary>
        /// Current Guidance object
        /// </summary>
        public Guidance Guidance
        {
            set
            {
                _guidance = value;
            }
        }
		/// <summary>
        /// The guidance nodes that will be displayed.
        /// </summary>
        public GuidanceNodeTypes NodeTypes
        {
            get { return _nodeTypes; }
            set { _nodeTypes = value; }
        }

        public TreeNode SelectedNode
        {
            get { return treeView.SelectedNode; }
        }

		#endregion

		#region TreeView Event Handlers
		private void ViewsBrowser_Load(object sender, EventArgs e)
		{
			// Create treeView nodes
			if (_nodeTypes == GuidanceNodeTypes.SearchViewLocation ||
				_nodeTypes == GuidanceNodeTypes.ReadWriteViews)
			{
                MyViewsNode myViews = MyViewsNode.New();
				if (_guidance != null)
				{
                    if (_guidance.SolutionViews != null)
                    {
                        SolutionNode solutionNode = SolutionNode.New();
                        solutionNode.Text = _guidance.SolutionViews.SolutionName;
                        treeView.Nodes.Add(solutionNode);

                        AddNodes(_guidance.SolutionViews.Folders, _guidance.SolutionViews.Views ,_guidance.SolutionViews.Checklists, solutionNode);

                    }
					// Add "my views" folder nodes
					treeView.Nodes.Add(myViews);
					if (_guidance.UserViews != null && _guidance.UserViews.Folders != null)
					{
						AddNodes(_guidance.UserViews.Folders, _guidance.UserViews.Views, null, myViews);
					}
				}
			}

			// Expand first-level nodes
			foreach (TreeNode node in treeView.Nodes)
			{
				node.Expand();
			}
		}
		private void btnOk_Click(object sender, EventArgs e)
		{
			DialogResult = DialogResult.OK;
			this.Close();
		}
		private void btnCancel_Click(object sender, EventArgs e)
		{
			DialogResult = DialogResult.Cancel;
			this.Close();
		}
		/// <summary>
		/// When a node is selected, check wich actions can be made
		/// </summary>
		private void treeView_AfterSelect(object sender, TreeViewEventArgs e)
		{
			if (e.Node is ViewNode || e.Node is ChecklistNode)
			{
				btnOk.Enabled = true;
				btnNewView.Enabled = false;
                btnNewChecklist.Enabled = false;
            }
            else
            {
                btnOk.Enabled = false;
                btnNewView.Enabled = true;
                btnNewChecklist.Enabled = CanContainChecklists(e.Node);
            }
        }

        private bool CanContainChecklists(TreeNode node)
        {
            if (node is SolutionNode)
            {
                return true;
            }
            if (node.Parent != null)
            {
                return CanContainChecklists(node.Parent);
            }
            return false;
        }

		/// <summary>
		/// Ocurrs when the user double clicked a TreeView node
		/// </summary>
		private void treeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
		{
			if (e.Node is ViewNode || e.Node is ChecklistNode)
			{
				DialogResult = DialogResult.OK;
				this.Close();
			}
		}
		/// <summary>
		/// Ocurrs when the user clicks views-creator button 
		/// </summary>
		private void btnNewView_Click(object sender, EventArgs e)
		{
			// Create node and assign dummy view
			ViewNode newNode = ViewNode.New();
            CreateNewNode(newNode, GEController.ControlsType.View);
            
            //newNode.Text = GEController.GetNewDefaultName(treeView.SelectedNode, GEController.ControlsType.View);
			
            //treeView.SelectedNode.Nodes.Add(newNode);
            //treeView.SelectedNode.Expand();
            //treeView.SelectedNode = newNode;

            //// Let the user edit the name of the new view
            //treeView.LabelEdit = true;
            //newNode.BeginEdit();
		}

        private void btnNewChecklist_Click(object sender, EventArgs e)
        {
            // Create node and assign dummy checklist
            ChecklistNode newNode = ChecklistNode.New();
            CreateNewNode(newNode, GEController.ControlsType.CheckList);
        }

        private void CreateNewNode(TreeNode newNode,GEController.ControlsType type)
        {
            newNode.Text = GEController.GetNewDefaultName(treeView.SelectedNode, type);
            treeView.SelectedNode.Nodes.Add(newNode);
            treeView.SelectedNode.Expand();
            treeView.SelectedNode = newNode;
            // Let the user edit the name of the new view
            treeView.LabelEdit = true;
            newNode.BeginEdit();
        }
		/// <summary>
		/// Occurs when the node has finished the edition mode.
		/// </summary>
		private void treeView_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
		{
			//Seems a bug in WinForms :)
			string newLabel = e.Label ?? e.Node.Text;

			//Check if the name exists
			TreeNodeCollection parentCollection = e.Node.Parent == null ? e.Node.TreeView.Nodes : e.Node.Parent.Nodes;
			foreach (TreeNode node in parentCollection)
			{
				if (node != e.Node && node.Text == newLabel)
				{
					MessageBox.Show(Messages.NODE_NAME_EXISTS, Messages.ERROR, MessageBoxButtons.OK, MessageBoxIcon.Error);
					e.CancelEdit = true;
					e.Node.BeginEdit();
					return;
				}
			}

			// The modification is valid, leave it to the handlers
            if (e.Node is ViewNode && OnNewView != null)
            {
                OnNewView(this, new NewViewEventArgs((ViewNode)e.Node, newLabel));
            }
            else if (e.Node is ChecklistNode && OnNewChecklist != null)
            {
                OnNewChecklist(this, new NewChecklistEventArgs((ChecklistNode)e.Node, newLabel));
            }
			treeView.LabelEdit = false;
			e.CancelEdit = false;
		}
		#endregion


	}
}
